package designModel.proxy;

import java.lang.reflect.*;

/**
 * 动态代理
 */
public abstract class DynamicShopProxy<T extends Shopping> {
    //被代理的对象
    private T market;

    /**
     * 获取代理
     *
     * @return 返回代理对象
     */
    public T getProxy() {
        setInstance();
        return (T) Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[]{Shopping.class}, new InvocationHandler() {
            /**
             *
             * @param proxy 被代理的对象
             * @param method 调用的方法
             * @param args 调用方法的参数
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("代理前的够沟通工作");
                return method.invoke(market, args);
            }
        });
    }

    /**
     * 根据泛型获取类的实例
     */
    private void setInstance() {
        //getClass().getGenericSuperclass()返回表示此 Class 所表示的实体（类、接口、基本类型或 void）的直接超类的 Type。
        Type type = getClass().getGenericSuperclass();

        //ParameterizedType表示参数化类型,具有<>符号的变量是参数化类型
        //也就是判断此类是不是一个泛型类
        if (type instanceof ParameterizedType) {

            //拿到泛型表示的具体类型
            Class<T> tClass = (Class<T>) ((ParameterizedType) type).getActualTypeArguments()[0];

            //获取实例
            try {
                market = tClass.getDeclaredConstructor().newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
